/*

* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Smart-Shop开源商城系统/ Java商城-首选电商平台系统 请务必保留此注释头信息
* |     开源地址: https://gitee.com/ningbo-qishan/gruul-mall
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     可正常分享和学习源码,未经授权 不可商用！
* |     商业版中台购买/开源版商业授权 联系技术客服
* |     官网:  https://www.73app.cn/
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Copyright (c) 2016-2999 宁波启山智软科技有限公司
* |     版权所有 ,侵权必究！
* ------------------------------------------------------------------------

*/
package com.medusa.gruul.solitaire.service.api.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medusa.gruul.common.core.constant.CommonConstants;
import com.medusa.gruul.common.core.exception.ServiceException;
import com.medusa.gruul.common.core.util.CurUserUtil;
import com.medusa.gruul.common.core.util.StringUtil;
import com.medusa.gruul.common.core.util.SystemCode;
import com.medusa.gruul.common.data.tenant.ShopContextHolder;
import com.medusa.gruul.common.data.tenant.TenantContextHolder;
import com.medusa.gruul.common.dto.CurUserDto;
import com.medusa.gruul.solitaire.api.constant.InformationReadRedisKey;
import com.medusa.gruul.solitaire.api.entity.*;
import com.medusa.gruul.solitaire.api.model.dto.api.ApiInformationMessageDto;
import com.medusa.gruul.solitaire.api.model.param.api.ApiInformationInfoParam;
import com.medusa.gruul.solitaire.api.model.param.api.ApiInformationMessageParam;
import com.medusa.gruul.solitaire.api.model.vo.api.ApiInformationInfoVo;
import com.medusa.gruul.solitaire.api.model.vo.api.ApiInformationMessageVo;
import com.medusa.gruul.solitaire.api.model.vo.api.ApiInformationSetVo;
import com.medusa.gruul.solitaire.mapper.api.*;
import com.medusa.gruul.solitaire.service.api.IApiInformationInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


/**
 * <p>
 * 小程序资讯信息 服务实现类
 * </p>
 *
 * @author lcysike
 * @since 2020-05-25
 */
@Service
public class ApiInformationInfoServiceImpl extends ServiceImpl<ApiInformationInfoMapper, InformationInfo> implements IApiInformationInfoService {

    @Autowired
    private ApiInformationSetMapper apiInformationSetMapper;

    @Autowired
    private ApiInformationTopicMapper apiInformationTopicMapper;

    @Autowired
    private ApiInformationMessageMapper apiInformationMessageMapper;

    @Autowired
    private ApiInformationLikeMapper apiInformationLikeMapper;

    @Autowired
    private ApiInformationMessageLikeMapper apiInformationMessageLikeMapper;

    /**
     * 获取资讯设置信息
     *
     * @return ApiInformationSetVo
     */
    @Override
    public ApiInformationSetVo getInformationSet() {
        InformationSet informationSet = apiInformationSetMapper.selectOne(new QueryWrapper<>());
        if(BeanUtil.isEmpty(informationSet)){
            throw new ServiceException("暂无资讯设置信息!", SystemCode.DATA_NOT_EXIST.getCode());
        }
        ApiInformationSetVo apiInformationSetVo = new ApiInformationSetVo();
        BeanUtil.copyProperties(informationSet, apiInformationSetVo);
        return apiInformationSetVo;
    }

    /**
     * 查询资讯专题信息
     *
     * @return List<ApiInformationTopicVo>
     */
    @Override
    public List<InformationTopic> topicList() {
        return apiInformationTopicMapper.selectList(new QueryWrapper<>());
    }

    /**
     * 获取资讯分页信息
     *
     * @param apiInformationInfoParam
     * @return 资讯分页对象
     */
    @Override
    public IPage<ApiInformationInfoVo> list(ApiInformationInfoParam apiInformationInfoParam) {
        IPage<ApiInformationInfoVo> page = new Page<>(apiInformationInfoParam.getCurrent(), apiInformationInfoParam.getSize());
        List<ApiInformationInfoVo> apiInformationInfoVos = this.baseMapper.queryList(page, apiInformationInfoParam);
        String shopId = ShopContextHolder.getShopId();
        String tenantId = TenantContextHolder.getTenantId();
        InformationReadRedisKey informationReadRedisKey = new InformationReadRedisKey();
        //遍历给资讯阅读量赋值
        apiInformationInfoVos.stream().forEach(apiInformationInfoVo -> {
            String readKey = tenantId + shopId + apiInformationInfoVo.getId();
            String count = informationReadRedisKey.get(readKey);
            if(StringUtil.isNotEmpty(count)){
                apiInformationInfoVo.setReadCount(count);
            }else{
                apiInformationInfoVo.setReadCount(String.valueOf(CommonConstants.NUMBER_ZERO));
            }
        });
        return page.setRecords(apiInformationInfoVos);
    }

    /**
     * 获取资讯信息明细
     *
     * @param id 资讯id
     * @return 资讯信息对象
     */
    @Override
    public ApiInformationInfoVo get(Long id) {
        String shopId = ShopContextHolder.getShopId();
        String tenantId = TenantContextHolder.getTenantId();
        InformationReadRedisKey informationReadRedisKey = new InformationReadRedisKey();
        CurUserDto curUserDto = CurUserUtil.getHttpCurUser();
        String userId = curUserDto.getUserId();
        //资讯阅读缓存key值 用户id+租户id+资讯id
        String readKey = tenantId + shopId + id;
        String count = informationReadRedisKey.get(readKey);
        //查询key值是否存在  存在+1 不存在设置为1
        if(StringUtil.isNotEmpty(count)){
            count = String.valueOf(Integer.valueOf(count));
        }else{
            count = String.valueOf(CommonConstants.NUMBER_ONE);
        }
        ApiInformationInfoVo apiInformationInfoVo = this.baseMapper.queryInfoById(id);
        //判断资讯是否点赞过
        if(BeanUtil.isNotEmpty(apiInformationInfoVo)){
            //资讯阅读数量赋值
            apiInformationInfoVo.setReadCount(count);
            Integer informationUserLikeCount = apiInformationLikeMapper.selectCount(new QueryWrapper<InformationLike>().eq("info_id", id).eq("user_id", userId));
            if(informationUserLikeCount > CommonConstants.NUMBER_ZERO ){
                apiInformationInfoVo.setInfoHasLike(true);
            }
            ApiInformationMessageParam apiInformationMessageParam = new ApiInformationMessageParam();
            apiInformationMessageParam.setInfoId(id);
            apiInformationMessageParam.setUserId(userId);
            ApiInformationMessageVo apiInformationMessageVo = apiInformationMessageMapper.queryMessage(apiInformationMessageParam);
            //自己的资讯留言是否点赞赋值
            if(BeanUtil.isNotEmpty(apiInformationMessageVo)){
                Integer messageUserLikeCount = apiInformationMessageLikeMapper.selectCount(new QueryWrapper<InformationMessageLike>().eq("message_id", apiInformationMessageVo.getId()).eq("user_id", userId));
                if(messageUserLikeCount > CommonConstants.NUMBER_ZERO ){
                    apiInformationMessageVo.setMessageHasLike(true);
                }
                apiInformationInfoVo.setInformationMessageVo(apiInformationMessageVo);
            }
        }
        return apiInformationInfoVo;
    }

    /**
     * 资讯阅读量增加
     *
     * @param id 资讯id
     */
    @Override
    public void setRead(Long id) {
        String shopId = ShopContextHolder.getShopId();
        String tenantId = TenantContextHolder.getTenantId();
        InformationReadRedisKey informationReadRedisKey = new InformationReadRedisKey();
        //资讯阅读缓存key值 用户id+租户id+资讯id
        String readKey = tenantId + shopId + id;
        String count = informationReadRedisKey.get(readKey);
        //查询key值是否存在  存在+1 不存在设置为1
        if(StringUtil.isNotEmpty(count)){
            count = String.valueOf(Integer.valueOf(count) + CommonConstants.NUMBER_ONE);
        }else{
            count = String.valueOf(CommonConstants.NUMBER_ONE);
        }
        informationReadRedisKey.set(readKey, count);
    }

    /**
     * 获取资讯留言分页信息
     *
     * @param apiInformationMessageParam
     * @return 资讯留言分页对象
     */
    @Override
    public IPage<ApiInformationMessageVo> getMessageList(ApiInformationMessageParam apiInformationMessageParam) {
        IPage<ApiInformationMessageVo> page = new Page<>(apiInformationMessageParam.getCurrent(), apiInformationMessageParam.getSize());
        List<ApiInformationMessageVo> apiInformationMessageVos = apiInformationMessageMapper.queryMessageList(page, apiInformationMessageParam);
        //给每条留言赋值是否点赞过
        if(CollectionUtil.isNotEmpty(apiInformationMessageVos)){
            CurUserDto curUserDto = CurUserUtil.getHttpCurUser();
            String userId = curUserDto.getUserId();
            apiInformationMessageVos.stream().forEach(apiInformationMessageVo -> {
                Integer messageUserLikeCount = apiInformationMessageLikeMapper.selectCount(new QueryWrapper<InformationMessageLike>().eq("message_id", apiInformationMessageVo.getId()).eq("user_id", userId));
                if(messageUserLikeCount > CommonConstants.NUMBER_ZERO ){
                    apiInformationMessageVo.setMessageHasLike(true);
                }
            });
        }
        return page.setRecords(apiInformationMessageVos);
    }

    /**
     * 资讯留言
     *
     * @param apiInformationMessageDto dto对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void leave(ApiInformationMessageDto apiInformationMessageDto) {
        CurUserDto curUserDto = CurUserUtil.getHttpCurUser();
        String userId = curUserDto.getUserId();
        InformationMessage informationMessage = apiInformationMessageMapper.selectOne(new QueryWrapper<InformationMessage>().eq("info_id", apiInformationMessageDto.getInfoId()).eq("user_id", userId));
        if(BeanUtil.isNotEmpty(informationMessage)){
            throw new ServiceException("您已评论!", SystemCode.DATA_EXISTED.getCode());
        }
        informationMessage = new InformationMessage();
        //新增资讯留言信息
        informationMessage.setUserContent(apiInformationMessageDto.getUserContent());
        informationMessage.setUserId(userId);
        informationMessage.setNickName(curUserDto.getNikeName());
        informationMessage.setAvatarUrl(curUserDto.getAvatarUrl());
        informationMessage.setUserSendTime(new Date());
        informationMessage.setInfoId(apiInformationMessageDto.getInfoId());
        int insert = apiInformationMessageMapper.insert(informationMessage);
        if (insert == 0) {
            throw new ServiceException("评论失败！", SystemCode.DATA_ADD_FAILED.getCode());
        }
    }

    /**
     * 资讯信息点赞
     *
     * @param type 操作类型 0-点赞 1-取消点赞
     * @param infoId 资讯id
     */
    @Override
    public void like(Integer type, Long infoId) {
        CurUserDto curUserDto = CurUserUtil.getHttpCurUser();
        String userId = curUserDto.getUserId();
        if(CommonConstants.NUMBER_ZERO.equals(type)){
            InformationLike informationLike = apiInformationLikeMapper.selectOne(new QueryWrapper<InformationLike>().eq("info_id", infoId).eq("user_id", userId));
            //查询是否存在点赞信息 不存在插入数据
            if(BeanUtil.isEmpty(informationLike)){
                informationLike = new InformationLike();
                informationLike.setInfoId(infoId);
                informationLike.setUserId(userId);
                int insert = apiInformationLikeMapper.insert(informationLike);
                if(insert == 0){
                    throw new ServiceException("点赞失败!", SystemCode.DATA_ADD_FAILED.getCode());
                }
            }else{
                throw new ServiceException("您已点赞过!", SystemCode.DATA_EXISTED.getCode());
            }
        }else{
            apiInformationLikeMapper.delete(new QueryWrapper<InformationLike>().eq("user_id", userId).eq("info_id", infoId));
        }
    }

    /**
     * 资讯留言点赞
     *
     * @param type 操作类型 0-点赞 1-取消点赞
     * @param messageId 资讯留言id
     */
    @Override
    public void messageLike(Integer type, Long messageId) {
        CurUserDto curUserDto = CurUserUtil.getHttpCurUser();
        String userId = curUserDto.getUserId();
        if(CommonConstants.NUMBER_ZERO.equals(type)){
            InformationMessageLike informationMessageLike = apiInformationMessageLikeMapper.selectOne(new QueryWrapper<InformationMessageLike>().eq("message_id", messageId).eq("user_id", userId));
            //查询是否存在点赞信息 存在说明是取消点赞 不存在说明是
            if(BeanUtil.isEmpty(informationMessageLike)){
                informationMessageLike = new InformationMessageLike();
                informationMessageLike.setMessageId(messageId);
                informationMessageLike.setUserId(userId);
                int insert = apiInformationMessageLikeMapper.insert(informationMessageLike);
                if(insert == 0){
                    throw new ServiceException("点赞失败!", SystemCode.DATA_ADD_FAILED.getCode());
                }
            }else{
                throw new ServiceException("您已点赞过!", SystemCode.DATA_EXISTED.getCode());
            }
        }else{
            apiInformationMessageLikeMapper.delete(new QueryWrapper<InformationMessageLike>().eq("user_id", userId).eq("message_id", messageId));
        }
    }

    /**
     * 资讯留言删除
     *
     * @param id 资讯留言id
     */
    @Override
    public void delete(Long id) {
        InformationMessage informationMessage = apiInformationMessageMapper.selectById(id);
        if(BeanUtil.isEmpty(informationMessage)){
            throw new ServiceException("评论不存在!", SystemCode.DATA_NOT_EXIST.getCode());
        }
        CurUserDto curUserDto = CurUserUtil.getHttpCurUser();
        String userId = curUserDto.getUserId();
        if(userId.equals(informationMessage.getUserId())){
            int delete = apiInformationMessageMapper.deleteById(id);
            if(delete == 0){
                throw new ServiceException("评论删除失败!", SystemCode.DATA_DELETE_FAILED.getCode());
            }
        }else{
            throw new ServiceException("该评论不允许删除!", SystemCode.DATA_DELETE_FAILED.getCode());
        }
    }

}
